package com.ljh.cloudmusic.service;

import com.ljh.cloudmusic.mapper.UserMapper;
import com.ljh.cloudmusic.model.User;
import com.ljh.cloudmusic.utils.JwtUtils;
import com.ljh.cloudmusic.utils.ResponseBodyMessage;
import jakarta.mail.MessagingException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;

/**
 * @author: Themberfue
 * @date: 2025/3/9 9:10
 * @description:
 */
@Service
public class UserService {
    @Value("${music.local.path}")
    private String SAVE_PATH;
    @Autowired
    MailService mailService;
    @Autowired
    UserMapper userMapper;
    @Autowired
    BCryptPasswordEncoder bCryptPasswordEncoder;
    public ResponseBodyMessage<String> login(@RequestParam String username, @RequestParam String password) {
        User user = userMapper.selectLoginByUsername(username);
        if (user == null) {
            return new ResponseBodyMessage<>(-1, "用户名不存在", null);
        }
        if (user.getPassword().equals("-1")) {
            return new ResponseBodyMessage<>(-1, "您未设置密码，请通过邮箱登录", null);
        }
        System.out.println(bCryptPasswordEncoder.matches(password, user.getPassword()));
        if (!bCryptPasswordEncoder.matches(password, user.getPassword())) {
            return new ResponseBodyMessage<>(-1, "密码错误", null);
        }

        // TODO 生成 JWT Token
        String token = JwtUtils.generateToken(username);

        return new ResponseBodyMessage<>(0, "登录成功", token);
    }

    public ResponseBodyMessage<String> register(String username, String password) {
        User tmpUser = userMapper.selectLoginByUsername(username);
        if (tmpUser != null) {
            return new ResponseBodyMessage<>(-1, "用户名已存在", null);
        }
        String newPassword = bCryptPasswordEncoder.encode(password);

        // TODO 生成唯一 ID，确保不会重复
        int uniqueId;
        do {
            uniqueId = ThreadLocalRandom.current().nextInt(10000, 99999); // 5位随机数
        } while (userMapper.selectUserByUUID(uniqueId) != null); // 确保唯一

        // TODO 存入数据库
        User user = User.builder()
                .uuid(uniqueId)
                .username(username)
                .password(newPassword)
                .build();
        userMapper.insertUserByUsername(user);

        // TODO 生成 JWT Token
        String token = JwtUtils.generateToken(username);
        return new ResponseBodyMessage<>(0, "注册账号成功", token);
    }
    private boolean validToken(HttpServletRequest request) {
        // TODO 从Authorization中获取 token
        String token = request.getHeader("Authorization");

        return token == null || !token.startsWith("Bearer ");
    }

    public ResponseBodyMessage<User> getUserInfo(HttpServletRequest request) {
        // TODO 验证 Token
        if (validToken(request)) {
            return new ResponseBodyMessage<>(-1, "未登录，请登录", null);
        }

        // TODO 去掉 "Bearer " 部分
        String token = request.getHeader("Authorization").substring(7);
        // TODO 从 token 中解析出 username
        String username = JwtUtils.getUsernameFromToken(token);

        if (username == null) {
            return new ResponseBodyMessage<>(-1, "Token 无效", null);
        }

        User user = userMapper.selectLoginByUsername(username);

        return new ResponseBodyMessage<>(0, "当前用户：" + username, user);
    }

    public ResponseBodyMessage<String> updateUserInfo(Map<String, Object> data, HttpServletRequest request) {
        // TODO 验证 Token
        if (validToken(request)) {
            return new ResponseBodyMessage<>(-1, "未登录，请登录", null);
        }

        Integer uuid = (Integer) data.get("uuid");
        String username = (String) data.get("username");
        String email = (String) data.get("email");
        Integer gender = (Integer) data.get("gender");
        String location = (String) data.get("location");

        // TODO 检查用户名是否已经存在
        String curUserName = JwtUtils.getUsernameFromToken(request.getHeader("Authorization").substring(7));
        if (curUserName != null && !curUserName.equals(username)) {
            User user = userMapper.selectLoginByUsername(username);
            if (user != null) {
                return new ResponseBodyMessage<>(-1, "用户名已存在", null);
            }
        }

        userMapper.updateUserInfo(uuid, username, email, gender, location);

        // TODO 重新生成token
        String token = JwtUtils.generateToken(username);

        return new ResponseBodyMessage<>(0, "更新个人资料成功", token);
    }

    public ResponseBodyMessage<Boolean> updatePassword(Integer uuid, String oldPassword, String newPassword, HttpServletRequest request) {
        // TODO 验证 Token
        if (validToken(request)) {
            return new ResponseBodyMessage<>(-1, "未登录，请登录", null);
        }
        String password = userMapper.selectUserByUUID(uuid);
        if (!bCryptPasswordEncoder.matches(String.valueOf(oldPassword), password)) {
            return new ResponseBodyMessage<>(-1, "原密码不正确", false);
        }

        String encodePassword = bCryptPasswordEncoder.encode(newPassword);
        userMapper.updatePasswordByUUID(uuid, encodePassword);

        return new ResponseBodyMessage<>(0, "修改密码成功", true);
    }

    public ResponseBodyMessage<Boolean> updateAvatar(Integer uuid, MultipartFile avatarFile, HttpServletRequest request) throws IOException {
        // TODO 验证 Token
        if (validToken(request)) {
            return new ResponseBodyMessage<>(-1, "未登录，请登录", null);
        }

        System.out.println("SAVE_PATH:" + SAVE_PATH);
        System.out.println("Current directory: " + new File(".").getAbsolutePath());
        File saveDir = new File(SAVE_PATH);
        if (!saveDir.exists()) {
            System.out.println("Directory does not exist: " + SAVE_PATH);
            boolean created = saveDir.mkdirs(); // 自动创建目录
            if (!created) {
                throw new IOException("Failed to create directory: " + SAVE_PATH);
            }
        }

        // TODO 得到文件名及存储路径
        String avatarFileName = uuid + "-avatar.png";
        String newAvatarPath = SAVE_PATH + avatarFileName;
        File avatar = new File(newAvatarPath);

        // TODO 将图片写入服务器
        avatarFile.transferTo(avatar);

        // TODO 将图片路径存入数据库
        String avatarUrl = "/user/getAvatar?path=" + avatarFileName;
        userMapper.updateAvatar(uuid, avatarUrl);

        return new ResponseBodyMessage<>(0, "更新头像成功", true);
    }

    public ResponseEntity<Resource> getAvatar(String path) {
        try {
            File avatarFile = new File(SAVE_PATH + path);
            System.out.println(avatarFile.getPath());
            if (!avatarFile.exists()) {
                return ResponseEntity.badRequest().build();
            }

            // TODO 读取图片并返回
            Resource fileResource = new UrlResource(avatarFile.toURI());
            return ResponseEntity.ok()
                    .contentType(MediaType.IMAGE_PNG)
                    .body(fileResource);
        } catch (MalformedURLException e) {
            return ResponseEntity.badRequest().build();
        }
    }

    Map<String, String> verifyCode = new HashMap<>();
    public ResponseBodyMessage<Boolean> sendCode(String email, String code, HttpServletRequest request) throws MessagingException {
        // TODO 生成邮件内容
        String subject = "验证您的新账户";
        String body = "尊敬的新用户，您的验证码为：" + code + "，该验证码5分钟内有效，请忽泄露于他人。";

        // TODO 存入 HashMap
        verifyCode.put("email", email);
        verifyCode.put("code", code);

        // TODO 发送邮件
        mailService.sendEmail(email, subject, body);
        return new  ResponseBodyMessage<>(0, "验证码已发送，请查收邮箱", true);
    }

    public ResponseBodyMessage<String> loginByEmailCode(String code, String email) {
        // TODO 通过邮箱查找是否存在该用户
        String username = userMapper.selectUserByEmail(email);
        if (username == null) {
            return new ResponseBodyMessage<>(-1, "该邮箱未被注册，请注册后再登录", null);
        }

        // TODO 验证邮箱和验证码
        ResponseBodyMessage<String> response = validEmailAndCode(code, email);
        if (response.getStatus() == -1) {
            return response;
        }

        // TODO 生成 JWT Token
        String token = JwtUtils.generateToken(username);

        return new ResponseBodyMessage<>(0, "验证码正确", token);
    }

    public ResponseBodyMessage<String> registerByEmailCode(String code, String email) {
        // TODO 通过邮箱查找是否存在该用户
        String username = userMapper.selectUserByEmail(email);
        if (username != null) {
            return new ResponseBodyMessage<>(-1, "该邮箱已被注册，请直接登录", null);
        }
        // TODO 验证邮箱和验证码
        ResponseBodyMessage<String> response = validEmailAndCode(code, email);
        if (response.getStatus() == -1) {
            return response;
        }

        // TODO 生成唯一 ID，确保不会重复
        int uniqueId;
        do {
            uniqueId = ThreadLocalRandom.current().nextInt(10000, 99999); // 5位随机数
        } while (userMapper.selectUserByUUID(uniqueId) != null); // 确保唯一

        username = "用户"+uniqueId;
        // TODO 存入数据库
        User user = User.builder()
                .uuid(uniqueId)
                .username(username)
                .email(email)
                .build();
        userMapper.insertUserByEmail(user);

        // TODO 生成 JWT Token
        String token = JwtUtils.generateToken(username);
        return new ResponseBodyMessage<>(0, "注册账号成功", token);
    }

    private ResponseBodyMessage<String> validEmailAndCode(String code, String email) {
        // TODO 验证邮箱和验证码是否一致
        String curCode = verifyCode.getOrDefault("code", null);
        String curEmail = verifyCode.getOrDefault("email", null);
        // TODO 验证是否发送了验证码
        if (curEmail == null) {
            return new ResponseBodyMessage<>(-1, "未正确向您发送验证码，请重试", null);
        }

        // TODO 验证邮箱和验证码是否一致
        if (!curEmail.equals(email)) {
            return new ResponseBodyMessage<>(-1, "输入的邮箱与发送至的邮箱不一致，请重试", null);
        }
        if (!curCode.equals(code)) {
            return new ResponseBodyMessage<>(-1, "验证码不正确，请重试", null);
        }
        return new ResponseBodyMessage<>(0, "验证通过", null);
    }

    public ResponseBodyMessage<String> getEmailByUsername(String username) {
        // TODO 验证用户是否存在
        User user = userMapper.selectLoginByUsername(username);
        if (user == null) {
            return new ResponseBodyMessage<>(-1, "用户名不存在", null);
        }
        // TODO 验证用户是否设置邮箱
        String email = userMapper.selectEmailByUsername(username);
        if (email == null || email.isEmpty()) {
            return new ResponseBodyMessage<>(-1, "您未设置邮箱", null);
        }
        return new ResponseBodyMessage<>(0, "获取邮箱成功", email);
    }


    public ResponseBodyMessage<String> updateNewPassword(String username, String newPassword) {
        System.out.println(newPassword);
        String encodePassword = bCryptPasswordEncoder.encode(newPassword);
        userMapper.updatePasswordByUsername(username, encodePassword);
        return new ResponseBodyMessage<>(0, "设置密码成功", null);
    }
}
